"""
Configuration management for InCloud MCP Server
"""
import yaml
import os
from typing import Dict, List, Optional, Any
from pydantic import BaseModel, Field
import logging

logger = logging.getLogger(__name__)


class APIConfig(BaseModel):
    """Configuration for a single API endpoint"""
    method: str = Field(description="HTTP method (GET, POST, etc.)")
    path: str = Field(description="API path")
    description: Optional[str] = Field(default="", description="API description")
    enabled: bool = Field(default=True, description="Whether this API is enabled")


class ServiceConfig(BaseModel):
    """Configuration for a service module"""
    enabled: bool = Field(default=True, description="Whether this service is enabled")
    apis: List[APIConfig] = Field(default_factory=list, description="List of APIs to register")


class AuthConfig(BaseModel):
    """Authentication configuration"""
    type: Optional[str] = Field(default=None, description="Auth type: bearer, basic, api_key")
    token: Optional[str] = Field(default=None, description="Auth token")
    username: Optional[str] = Field(default=None, description="Username for basic auth")
    password: Optional[str] = Field(default=None, description="Password for basic auth")
    api_key: Optional[str] = Field(default=None, description="API key")
    api_key_header: Optional[str] = Field(default="X-API-Key", description="API key header name")


class MethodPolicyConfig(BaseModel):
    """HTTP method specific security policy"""
    default_level: str = Field(default="moderate", description="Default security level for this method")
    safe_patterns: List[str] = Field(default_factory=list, description="Patterns that are safe for this method")
    high_risk_patterns: List[str] = Field(default_factory=list, description="Patterns that are high-risk for this method")
    forbidden_patterns: List[str] = Field(default_factory=list, description="Patterns that are forbidden for this method")
    exceptions: List[str] = Field(default_factory=list, description="Exception patterns")


class ServiceResourceConfig(BaseModel):
    """Service resource specific security configuration"""
    allow_delete: bool = Field(default=True, description="Allow delete operations")
    allow_restart: bool = Field(default=True, description="Allow restart operations")
    allow_stop: bool = Field(default=True, description="Allow stop operations")
    require_backup_check: bool = Field(default=False, description="Require backup check before destructive operations")


class ServicePolicyConfig(BaseModel):
    """Service specific security policy"""
    vhosts: Optional[ServiceResourceConfig] = Field(default=None, description="Virtual hosts policy")
    vms: Optional[ServiceResourceConfig] = Field(default=None, description="Virtual machines policy")
    volumes: Optional[ServiceResourceConfig] = Field(default=None, description="Storage volumes policy")


class SecurityConfig(BaseModel):
    """Security configuration"""
    enabled: bool = Field(default=True, description="Enable security control")
    method_policies: Dict[str, MethodPolicyConfig] = Field(default_factory=dict, description="HTTP method specific policies")
    path_whitelist: List[str] = Field(default_factory=list, description="Path whitelist patterns (regex)")
    path_blacklist: List[str] = Field(default_factory=list, description="Path blacklist patterns (regex)")
    service_policies: Dict[str, ServicePolicyConfig] = Field(default_factory=dict, description="Service specific policies")
    require_confirmation_for_high_risk: bool = Field(default=True, description="Require confirmation for high-risk operations")

    # 保持向后兼容性
    whitelist: List[str] = Field(default_factory=list, description="Legacy API whitelist patterns (regex)")
    blacklist: List[str] = Field(default_factory=list, description="Legacy API blacklist patterns (regex)")
    forbidden_operations: List[str] = Field(default_factory=list, description="Legacy forbidden operation types")


class SwaggerConfig(BaseModel):
    """Swagger configuration"""
    base_url: str = Field(description="Base URL for Swagger API")
    timeout: int = Field(default=30, description="Request timeout in seconds")


class InCloudConfig(BaseModel):
    """Main configuration for InCloud MCP Server"""
    swagger: SwaggerConfig
    services: Dict[str, ServiceConfig] = Field(default_factory=dict)
    auth: Optional[AuthConfig] = Field(default=None)
    security: Optional[SecurityConfig] = Field(default=None)
    language: str = Field(default="en", description="Language for AI prompts: 'en' or 'cn'")
    
    @classmethod
    def load_from_file(cls, config_path: str) -> 'InCloudConfig':
        """Load configuration from YAML file"""
        if not os.path.exists(config_path):
            raise FileNotFoundError(f"Configuration file not found: {config_path}")
        
        with open(config_path, 'r', encoding='utf-8') as f:
            config_data = yaml.safe_load(f)
        
        return cls(**config_data)
    
    def get_enabled_services(self) -> Dict[str, ServiceConfig]:
        """Get all enabled services"""
        return {name: config for name, config in self.services.items() if config.enabled}
    
    def get_service_apis(self, service_name: str) -> List[APIConfig]:
        """Get enabled APIs for a specific service"""
        if service_name not in self.services:
            return []
        
        service = self.services[service_name]
        if not service.enabled:
            return []
        
        return [api for api in service.apis if api.enabled]


# Global configuration instance
config: Optional[InCloudConfig] = None


def load_config(config_path: str = "config.yaml") -> InCloudConfig:
    """Load and set global configuration"""
    global config
    config = InCloudConfig.load_from_file(config_path)
    logger.info(f"Configuration loaded from {config_path}")
    return config


def get_config() -> InCloudConfig:
    """Get current configuration"""
    if config is None:
        raise RuntimeError("Configuration not loaded. Call load_config() first.")
    return config
